package com.hdax.dmw.utils.auth;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.hdax.dmw.utils.Result;
import com.hdax.dmw.utils.ResultGenerator;
import com.hdax.dmw.utils.TokenUtil;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;

    //在进入controller之前执行
    //true 可以执行controller方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();
        //保证用户认证之后方可访问指定的controller token
        //判断请求路径中是否包含指定的uri
        // /item/index/nav
        // /order/p/ticketbuyerlist
        String requestURI = request.getRequestURI();
        String[] uris = requestURI.split("/");
        if(uris[2].equals("p")) {
            //1. 获取用户请求时携带的token
            String token = request.getHeader("token");
            String md5 = request.getHeader("md5");
            //2. 调用TokenUtil检查token的有效性
            if (token == null || token.equals("")) {
                //用户未登录
                Result<String> result = ResultGenerator.genErrorResult("9999", "当前用户未登录");
                outputStream.write(JSONUtil.toJsonStr(result).getBytes(StandardCharsets.UTF_8));
                return false;
            }
            Map<String, String> tokenMap = null;
            try {
                tokenMap = TokenUtil.parseToken(token);
            } catch (Exception e) {
                if (e instanceof ExpiredJwtException) {
                    //本地缓存token过期
                    //从redis获取用户信息
                    //判断缓存信息是否过期
                    if (redisTemplate.hasKey("token:" + md5)) {
                        Map entries = redisTemplate.opsForHash().entries("token:" + md5);
                        //无需用户重新登录，只需要前端再次发起获取token的请求即可
                        Result<String> result = ResultGenerator.genErrorResult("9998", "重新置换token");
                        outputStream.write(JSONUtil.toJsonStr(result).getBytes(StandardCharsets.UTF_8));
                    } else {
                        //缓存信息已过期，需要重新登录
                        Result<String> result = ResultGenerator.genErrorResult("9999", "登录已过期");
                        outputStream.write(JSONUtil.toJsonStr(result).getBytes(StandardCharsets.UTF_8));
                    }
                }
                return false;
            }
        }
        return true;
    }
}
